package org.next.tesigiulia.views;

import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
import net.miginfocom.swing.MigLayout;
import org.next.tesigiulia.controllers.IAreaController;
import org.next.tesigiulia.models.Area;
import org.next.tesigiulia.models.AreasModel;
import org.next.tesigiulia.utils.MyConstant;
import org.next.tesigiulia.utils.MyEventBus;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.*;
import java.text.Format;
import java.text.NumberFormat;
import java.util.ArrayList;


public class AreaView extends JFrame {

    private JLabel lblArea;
    private JLabel lblLatitudine;
    private JLabel lblLongitudine;
    private JLabel lblRaggio;
    private JTextField txtArea;

    private JFormattedTextField txtLatitudine;
    private JFormattedTextField txtLongitudine;
    private JSlider barRaggio;

    private JPanel pannelloInfo;
    private JPanel pannelloDatiMemorizzati;
    private JScrollPane scrollPane;
    private Format general;
    private DefaultListModel model;
    private JList list;
    private JButton btnClear;
    private JButton btnModifica;
    private JButton btnElimina;
    private JButton btnAdd;
    private JButton btnAdd2;
    private JButton btnAnnulla;
    private JButton btnApply;
    private IAreaController controller;

    public void setController(IAreaController controller) {
        this.controller = controller;
    }

    public AreaView() {
        this.setLayout(new BorderLayout());
        this.setSize(700, 400);
        this.setResizable(false);
        this.setTitle(MyConstant.TITOLOFINESTRA_DETTAGLI);

        this.setIconImage(new ImageIcon("TwitterLogo.gif").getImage());
        this.setLocationRelativeTo(null);

        //Aggiungo  Jpanel al Frame
        this.add(getPannelloDatiMemorizzati());
        this.add(getPannelloInfo(), BorderLayout.EAST);

        getPannelloInfo().setLayout(new MigLayout());
        getPannelloInfo().add(getlblArea());
        getPannelloInfo().add(getTxtArea(), "span, grow, wrap");
        getPannelloInfo().add(getLblLatitudine());
        getPannelloInfo().add(getTxtLatitudine(), "span, grow,wrap");
        getPannelloInfo().add(getLblLongitudine());
        getPannelloInfo().add(getTxtLongitudine(), "span, grow,wrap");
        getPannelloInfo().add(getlblRaggio());
        getPannelloInfo().add(getSldRadius(), "span, grow, wrap");
        getPannelloInfo().add(getBtnClear(), "gap");
        getPannelloInfo().add(getBtnModifica(), "gap");
        getPannelloInfo().add(getBtnApply(), "gap");
        getPannelloInfo().add(getBtnAnnulla(), "gap");
        getPannelloInfo().add(getBtnAdd(), "grow,wrap");

        getPannelloDatiMemorizzati().setLayout(new MigLayout());
        getPannelloDatiMemorizzati().add(getJScrollPane(), "span,grow, wrap");
        getPannelloDatiMemorizzati().add(getBtnNew(), "grow");
        getPannelloDatiMemorizzati().add(getBtnElimina(), "span,grow");
        this.setAlwaysOnTop(true);
        this.pack();
        addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent we){
                controller.frameClosed();
            }
        });

        MyEventBus.getInstance().getEventBus().register(this);
    }


    private JPanel getPannelloDatiMemorizzati() {
        if (pannelloDatiMemorizzati == null) {
            pannelloDatiMemorizzati = new JPanel();
            pannelloDatiMemorizzati.setLayout(null);
            pannelloDatiMemorizzati.setName(MyConstant.LBL_PANNELLODATIMEMORIZZATI);
            pannelloDatiMemorizzati.setBorder(BorderFactory.createTitledBorder(null, "Available Areas", TitledBorder.ABOVE_TOP, TitledBorder.DEFAULT_POSITION, new Font("Arial", Font.BOLD, 12), Color.BLACK));
        }
        return pannelloDatiMemorizzati;
    }

    private JPanel getPannelloInfo() {
        if (pannelloInfo == null) {
            pannelloInfo = new JPanel();
            pannelloInfo.setName(MyConstant.LBL_PANNELLOINFO);
            pannelloInfo.setBorder(BorderFactory.createTitledBorder(null, "", TitledBorder.ABOVE_TOP, TitledBorder.DEFAULT_POSITION, new Font("Arial", Font.BOLD, 12), Color.BLACK));
            pannelloInfo.setVisible(true);
        }
        return pannelloInfo;
    }

    private DefaultListModel getModel() {
        if (model == null) {
            model = new DefaultListModel();
        }
        return model;
    }

    private JList getList() {
        if (list == null) {
            list = new JList(getModel());
            list.setName(MyConstant.AREA_VIEW_LIST);
            list.setSelectionModel(new DefaultListSelectionModel() {
                boolean selected = false;

                @Override
                public void setSelectionInterval(int index0, int index1) {
                    if (!selected) {
                        if (index0 == index1) {
                            if (isSelectedIndex(index0)) {
                                removeSelectionInterval(index0, index0);
                                return;
                            }
                        }
                        super.setSelectionInterval(index0, index1);
                    }
                    selected = true;
                }

                @Override
                public void setValueIsAdjusting(boolean isAdjusting) {
                    if (isAdjusting == false) {
                        controller.selectedIndexChanged(list.getSelectedIndex());
                        selected = false;
                    }
                }

            });
            list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            list.setFixedCellWidth(280);
            list.setVisibleRowCount(10);
        }
        return list;
    }

    private JScrollPane getJScrollPane() {
        if (scrollPane == null) {
            scrollPane = new JScrollPane(getList());

        }
        return scrollPane;
    }

    private JLabel getlblArea() {
        if (lblArea == null) {
            lblArea = new JLabel(MyConstant.AREA);
            lblArea.setName(MyConstant.AREA_VIEW_LBL_AREA_NAME);
            lblArea.setVisible(true);
        }
        return lblArea;
    }

    private JLabel getLblLatitudine() {
        if (lblLatitudine == null) {
            lblLatitudine = new JLabel(MyConstant.LATITUDINE);
            lblLatitudine.setName(MyConstant.AREA_VIEW_LBL_LATITUDINE);
            lblLatitudine.setVisible(true);
        }
        return lblLatitudine;
    }

    private JLabel getLblLongitudine() {
        if (lblLongitudine == null) {
            lblLongitudine = new JLabel(MyConstant.LONGITUDINE);
            lblLongitudine.setName(MyConstant.AREA_VIEW_LBL_LONGITUDINE);

        }
        return lblLongitudine;
    }

    private JLabel getlblRaggio() {
        if (lblRaggio == null) {
            lblRaggio = new JLabel(MyConstant.RAGGIO);
            lblRaggio.setName(MyConstant.AREA_VIEW_LBL_RAGGIO);
        }
        return lblRaggio;
    }

    private JTextField getTxtArea() {
        if (txtArea == null) {
            txtArea = new JTextField(10);
            txtArea.setName(MyConstant.AREA_VIEW_TXT_AREA_NAME);
            txtArea.addFocusListener(new FocusListener() {
                @Override
                public void focusGained(FocusEvent e) {
                   //To change body of implemented methods use File | Settings | File Templates.
                }

                @Override
                public void focusLost(FocusEvent e) {
                    controller.txtAreaChanged(txtArea.getText());
                }
            });
            }
        return txtArea;
    }

    private JFormattedTextField getTxtLatitudine() {
        if (txtLatitudine == null) {
            general = NumberFormat.getInstance();
            txtLatitudine = new JFormattedTextField(general);

            txtLatitudine.setName(MyConstant.AREA_VIEW_TXT_LATITUDINE);

            txtLatitudine.addFocusListener(new FocusListener() {
                @Override
                public void focusGained(FocusEvent e) {
                    //To change body of implemented methods use File | Settings | File Templates.
                }

                @Override
                public void focusLost(FocusEvent e) {
                    controller.txtLatitudeChanged(txtLatitudine.getText());

                }
            });
        }
        return txtLatitudine;

    }


    private JFormattedTextField getTxtLongitudine() {
        if (txtLongitudine == null) {
            txtLongitudine = new JFormattedTextField(NumberFormat.getInstance());
            txtLongitudine.setName(MyConstant.AREA_VIEW_TXT_LONGITUDINE);
            txtLatitudine.addFocusListener(new FocusListener() {
                @Override
                public void focusGained(FocusEvent e) {
                    //To change body of implemented methods use File | Settings | File Templates.
                }

                @Override
                public void focusLost(FocusEvent e) {
                    controller.txtLongitudineChanged(txtLongitudine.getText());
                }
            });
        }
        return txtLongitudine;

    }
    private JSlider getSldRadius() {
        if (barRaggio == null) {
            barRaggio = new JSlider(JSlider.HORIZONTAL, MyConstant.VALOREMINRAGGIO, MyConstant.VALOREMAXRAGGIO, MyConstant.VALORERAGGIOINIZIALE);
            barRaggio.setMajorTickSpacing(30);
            barRaggio.setMinorTickSpacing(10);
            barRaggio.setPaintTicks(true);
            barRaggio.setPaintLabels(true);
            barRaggio.setName(MyConstant.AREA_VIEW_SLD_RAGGIO);
            barRaggio.setValue(MyConstant.VALORERAGGIOINIZIALE);

            barRaggio.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    Integer radius = barRaggio.getValue();
                    controller.sldRadiusChanged(radius);
                }
            });
        }
        return barRaggio;
    }

    private JButton getBtnClear() {
        if (btnClear == null) {
            btnClear = new JButton(MyConstant.CLEAR);
            btnClear.setName(MyConstant.AREA_VIEW_BTN_CLEAR);
            btnClear.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    controller.btnClearClicked();
                }
            });
        }
        return btnClear;
    }

    private JButton getBtnAnnulla() {
        if (btnAnnulla == null) {
            btnAnnulla = new JButton(MyConstant.ANNULLA);
            btnAnnulla.setName(MyConstant.AREA_VIEW_BTN_ANNULLA);
            btnAnnulla.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    controller.btnAnnullaClicked();
                }
            });
        }
        return btnAnnulla;
    }

    private JButton getBtnAdd() {
        if (btnAdd == null) {
            btnAdd = new JButton(MyConstant.ADD);
            btnAdd.setName(MyConstant.AREA_VIEW_BTN_ADD);
            btnAdd.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    controller.btnAddClicked();
                }
            });
        }
        return btnAdd;
    }

    private JButton getBtnModifica() {
        if (btnModifica == null) {
            btnModifica = new JButton(MyConstant.MODIFICA);
            btnModifica.setName(MyConstant.AREA_VIEW_BTN_MODIFICA);
            btnModifica.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    controller.btnModificaClicked(list.getSelectedIndex());
                }
            });
        }
        return btnModifica;

    }

    private JButton getBtnElimina() {
        if (btnElimina == null) {
            btnElimina = new JButton(MyConstant.DELETE);
            btnElimina.setName(MyConstant.AREA_VIEW_BTN_DELETE);
            btnElimina.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    controller.btnEliminaClicked(list.getSelectedIndex());
                }
            });

        }
        return btnElimina;
    }

    private JButton getBtnNew() {
        if (btnAdd2 == null) {
            btnAdd2 = new JButton(MyConstant.ADD2);
            btnAdd2.setName(MyConstant.AREA_VIEW_BTN_ADD2);
            btnAdd2.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    controller.btnNewClicked();
                    getTxtArea().requestFocusInWindow();
                }
            });
        }
        return btnAdd2;
    }

    private JButton getBtnApply() {
        if (btnApply == null) {
            btnApply = new JButton(MyConstant.APPLY);
            btnApply.setName(MyConstant.AREA_VIEW_BTN_APPLY);
            btnApply.addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent actionEvent) {
                    controller.btnApplyClicked();
                }
            });
        }
        return btnApply;
    }


    @Subscribe
    @AllowConcurrentEvents
    public void handleData(AreasModel areasModel) {

        this.getPannelloInfo().setVisible(areasModel.isPannelloInfoVisile());

        this.getTxtArea().setEnabled(areasModel.isTxtAreaEnabled());
        this.getTxtLatitudine().setEnabled(areasModel.isTxtLatitudeEnabled());
        this.getTxtLongitudine().setEnabled(areasModel.isTxtLongitudeEnabled());
        this.getSldRadius().setEnabled(areasModel.isBarRaggioEnabled());

        this.getlblArea().setEnabled(areasModel.isLblAreaEnabled());
        this.getLblLatitudine().setEnabled(areasModel.isLblLatitudeEnabled());
        this.getLblLongitudine().setEnabled(areasModel.isLblLongitudeEnabled());
        this.getlblRaggio().setEnabled(areasModel.isLblRaggioEnabled());

        this.getBtnAdd().setEnabled(areasModel.isBtnAddEnabled());
        this.getBtnAnnulla().setEnabled(areasModel.isBtnAnnullaEnabled());
        this.getBtnClear().setEnabled(areasModel.isBtnClearEnabled());
        this.getBtnNew().setEnabled(areasModel.isBtnAdd2Enabled());
        this.getBtnModifica().setEnabled(areasModel.isBtnModificaEnabled());
        this.getBtnElimina().setEnabled(areasModel.isBtnModificaEnabled());
        this.getBtnApply().setEnabled(areasModel.isBtnApplyEnabled());

        this.getTxtArea().setBorder(areasModel.getTxtAreaBorderColorEnabled());
        this.getTxtLatitudine().setBorder(areasModel.getTxtLatitudineBorderColorEnabled());
        this.getTxtLongitudine().setBorder(areasModel.getTxtLongitudineBorderColorEnabled());
        this.getList().setEnabled(areasModel.isListEnabled());
        this.setVisible(areasModel.isJframeVisible());

    }

    @Subscribe
    public void handleList(ArrayList<Area> list) {
        this.getModel().clear();
        for (int i = 0; i < list.size(); i++) {
            getModel().add(i, list.get(i));
        }
    }

    @Subscribe
    public void handleCurrentAreaChange(Area area) {

        this.getTxtArea().setText(area.getAreaName());
        this.getTxtLatitudine().setValue(area.getLatitudine());
        this.getTxtLongitudine().setValue(area.getLongitudine());
        this.getSldRadius().setValue(area.getRaggio());
    }
}
